package cn.xhz.gdal.action;

import cn.hutool.core.io.FileUtil;
import cn.xhz.gdal.config.CommonConfig;
import cn.xhz.gdal.config.ConfigUtil;
import cn.xhz.gdal.constant.GDALGlobalConstanst;
import cn.xhz.gdal.exception.GDALException;
import cn.xhz.gdal.model.GDAL;
import cn.xhz.gdal.util.StringUtil;
import javafx.util.Builder;
import org.gdal.ogr.DataSource;
import org.gdal.ogr.Driver;
import org.gdal.ogr.Layer;
import org.gdal.ogr.ogrConstants;
import org.gdal.osr.SpatialReference;

import java.io.File;
import java.util.Vector;

/**
 * 创建<br/>
 * 考虑是否都迁移
 * 除开创建图层之外，数据源是必须，其它操作图层是必须<br/>
 * 都以{@link cn.xhz.gdal.model.GDAL} 对象包装
 * 但不会自动关闭，操作对象之后，请参照读做关闭操作
 * @see GDALRead
 *
 * @author life-oss
 * @since 2022/12/13
 */
public class GDALCreate extends CommonConfig {
    /**
     * 创建数据源的配置参数集合
     */
    private Vector<String> datasourceVector=new Vector<>();
    //=======================================图层配置开始=======================================
    /**
     * 数据源
     * 可以直接给，这样就代表只是作为创建图层
     */
    private DataSource dataSource;
    /**
     * 图层名称
     */
    private String name="layer";
    /**
     * 参数配置集合
     */
    private Vector<String> layerVector=initVector();
    /**
     * 空间参考
     */
    private SpatialReference spatialReference=initSpatialReference();
    /**
     * 绘制形状
     */
    private int geomType = ogrConstants.wkbPoint;
    //===========================================图层配置结束=======================================
    /**
     * 初始化编码
     * @return 默认会有一个UTF-8的编码配置
     */
    private Vector<String> initVector(){
        Vector<String> vectorInit = new Vector<>();
        vectorInit.add(GDALGlobalConstanst.UTF_8_ENCODING);
        return vectorInit;
    }

    /**
     * 默认参考为4490
     * @return
     */
    private SpatialReference initSpatialReference(){
        SpatialReference spatialReferenceInit = new SpatialReference();
        spatialReferenceInit.ImportFromEPSG(4490);
        return spatialReferenceInit;
    }


    //=====================================主要方法=================================
    /**
     * 创建
     * @return
     */
    public GDAL create(){
        //判断当前数据源是否有值
        GDAL.GDALBuilder gdalBuilder=GDAL.builder();
        try {
            if (getDataSource()==null) {
                if (StringUtil.isBlank(getPath())){
                    throw new GDALException("未传路径");
                }
                //检查路径是否存在
                File file = FileUtil.file(getPath());
                File parentFile = file.getParentFile();
                if (!parentFile.exists()){
                    parentFile.mkdirs();
                }
                String path = getPath();
                Driver driver = getDriver();
                gdalBuilder.dataSource(getDatasourceVector().isEmpty()?driver.CreateDataSource(path):driver.CreateDataSource(path,getDatasourceVector()));
                setDataSource(gdalBuilder.build().getDataSource());
            }else {
                gdalBuilder.dataSource(getDataSource());
            }
            gdalBuilder.layer(createLayer());
            return gdalBuilder.build();
        } catch (GDALException e) {
            ConfigUtil.stopContext(gdalBuilder.build());
            throw new GDALException(e.getMessage());
        }
    }

    /**
     * 创建图层
     *
     * @return {@link Layer}
     */
    public Layer createLayer(){
        return this.dataSource
                .CreateLayer(this.name,this.spatialReference,this.geomType,this.layerVector);
    }
    //====================================================================================
    //默认生成方法========================

    public DataSource getDataSource() {
        return dataSource;
    }

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public SpatialReference getSpatialReference() {
        return spatialReference;
    }

    public void setSpatialReference(SpatialReference spatialReference) {
        this.spatialReference = spatialReference;
    }

    public int getGeomType() {
        return geomType;
    }

    public void setGeomType(int geomType) {
        this.geomType = geomType;
    }

    public Vector<String> getDatasourceVector() {
        return datasourceVector;
    }

    public void setDatasourceVector(Vector<String> datasourceVector) {
        this.datasourceVector = datasourceVector;
    }

    public Vector<String> getLayerVector() {
        return layerVector;
    }

    public void setLayerVector(Vector<String> layerVector) {
        this.layerVector = layerVector;
    }
    //参数构造器
    public static GDALCreateBuilder builder(){
        return new GDALCreateBuilder();
    }
    public static class GDALCreateBuilder implements Builder<GDALCreate> {
        GDALCreate gdalCreate=new GDALCreate();
        public GDALCreateBuilder datasource(DataSource dataSource){
            gdalCreate.setDataSource(dataSource);
            return this;
        }
        public GDALCreateBuilder name(String name){
            gdalCreate.setName(name);
            return this;
        }
        public GDALCreateBuilder layerVector(Vector<String> layerVector){
            gdalCreate.setLayerVector(layerVector);
            return this;
        }
        public GDALCreateBuilder spatialReference(SpatialReference spatialReference){
            gdalCreate.setSpatialReference(spatialReference);
            return this;
        }
        public GDALCreateBuilder geomType(int geomType) {
            gdalCreate.setGeomType(geomType);
            return this;
        }
        public GDALCreateBuilder path(File file){
            gdalCreate.setPath(file);
            return this;
        }
        public GDALCreateBuilder path(String path){
            gdalCreate.setPath(path);
            return this;
        }
        @Override
        public GDALCreate build() {
            return gdalCreate;
        }
    }
}
